package CamposDePotencial;


import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;

import javax.vecmath.Point3d;

import CamposDePotencial.FabricaPotenciales.TIPOS_OBJETOS;
import comunicacion.Conector;
import estrategia.Vector;


public class EstrategiaCampoPotencial {

	private CampoPotencial[] campos;
	private FabricaPotenciales fabrica;
	
	private Properties prop;
	private final String pathConfig = "src/CamposDePotencial/Configuracion/DatosObjetos.properties";
	
	
	/**
	 * @param conector
	 */
	public EstrategiaCampoPotencial(Conector conector) {
		fabrica = new FabricaPotenciales();
		campos = fabrica.obtenerCampos(conector);
		
		prop = new Properties();
		try {
			InputStream istream = new FileInputStream(pathConfig);
			prop.load(istream);
			
		} catch (FileNotFoundException e) {
			System.out.println("No se encontro el archivo de configuracion: " + pathConfig);
		} catch (IOException e) {
			System.out.println("Se produjo un error al levantar el archivo de configuracion");
		}
		
	}
	
	public Point3d mapear(String objeto) throws IOException {
		return fabrica.mapearObjeto(objeto);
	}
	
	
	
	/*** Realiza la suma de vectores ***/
	private Vector sumaVectores(Vector vectorA, Vector vectorB) {
		// Pasamos de polar a escalar
		if(vectorA.getMagnitud()==0){ return vectorB;}
		if(vectorB.getMagnitud()==0){ return vectorA;}
		//double xa = (double)(Math.cos(vectorA.getDireccion() * Math.PI/180)*vectorA.getMagnitud());
		//double xb = (double)(Math.cos(vectorB.getDireccion() * Math.PI/180)*vectorB.getMagnitud());
		double xa = (double)(Math.cos(vectorA.getDireccion())*vectorA.getMagnitud());
		double xb = (double)(Math.cos(vectorB.getDireccion())*vectorB.getMagnitud());
		
		//double ya = (double)(Math.sin(vectorA.getDireccion() * Math.PI/180)*vectorA.getMagnitud());
		//double yb = (double)(Math.sin(vectorB.getDireccion() * Math.PI/180)*vectorB.getMagnitud());
		double ya = (double)(Math.sin(vectorA.getDireccion())*vectorA.getMagnitud());
		double yb = (double)(Math.sin(vectorB.getDireccion())*vectorB.getMagnitud());
		
		double xt = xa + xb;
		double yt = ya + yb;
		
		// pasamos de escalar a polar
		double radianes = 0;
		if (xt == 0) {
			radianes = Math.signum(yt)*Math.PI/2;
		} else 
			radianes = (double)(Math.atan(yt/xt));
		double direccion = radianes * (180/Math.PI);
		// Averiguamos el cuadrante
		if((xt>=0) && (yt>=0)){
			// Primer cuadrante
			//direccion = direccion;
		} else if ((xt<0)&&(yt>=0)) {
			// Segundo cuadrante
			direccion = 180 + direccion;			
		} else if ((xt<0)&&(yt<0)){
			// Tercer cuadrante
			direccion = -180 + direccion;
		} else {
			// Cuarto cuadrante
			direccion = direccion;
		}
			
		double magnitud = (double)(Math.sqrt((xt*xt)+(yt*yt)));
		
		Vector vectorSuma = new Vector(magnitud, Math.toRadians(direccion));
		return vectorSuma;
	}
	
	
	public Vector SumarFuerzas(Point3d mipos) throws IOException {
		
		Vector f1 = campos[0].obtenerFuerza(mipos);
		Vector f2 = campos[1].obtenerFuerza(mipos);
		Vector resultante = sumaVectores(f1, f2);
		for (int i= 2; i< campos.length; i++) {
			f1 = campos[i].obtenerFuerza(mipos);
			resultante = sumaVectores(resultante, f1);
		}
		
		return resultante;
	}
	
	
	public Point3d mapearPuntoDestino(Point3d mipos, Point3d objetivo, Vector resultante) {
		Point3d destino = new Point3d();
		double gananciaMagnitudDistancia = Double.parseDouble(prop.getProperty("GANANCIA_MAGNITUD_DISTANCIA"));
		
		 
		if (resultante.getMagnitud() >= 0.5) {
			//double mag = Math.sqrt(resultante.getMagnitud());
			//destino.x = (mag)*Math.cos(resultante.getDireccion())/gananciaMagnitudDistancia + mipos.x;
			//destino.y = (mag)*Math.sin(resultante.getDireccion())/gananciaMagnitudDistancia + mipos.y;
			double mag = resultante.getMagnitud();
			destino.x = (resultante.getMagnitud())*Math.cos(resultante.getDireccion())/gananciaMagnitudDistancia + mipos.x;
			destino.y = (resultante.getMagnitud())*Math.sin(resultante.getDireccion())/gananciaMagnitudDistancia + mipos.y;
			System.out.println("El cos es: " + resultante.getMagnitud()*Math.cos(resultante.getDireccion())/gananciaMagnitudDistancia + " el seno es: " + resultante.getMagnitud()*Math.sin(resultante.getDireccion())/gananciaMagnitudDistancia);
		} else {
			destino = objetivo;
		}
		
		return destino;
	}
	
	public boolean esObjetivoEjercito() {
		boolean esEjercito = false;
		
		for (int i=0; i<campos.length; i++) {
			if (campos[i].objeto.getTipo() == TIPOS_OBJETOS.EJERCITO) {
				esEjercito = true;
				break;
			}
		}
		return esEjercito;
	}
	
	public Point3d getDestino(Point3d mipos, Point3d objetivo) throws IOException {
		Vector resultante = SumarFuerzas(mipos);
		
		Point3d destino = mapearPuntoDestino(mipos, objetivo, resultante); 
		System.out.println("La direccion es = " + resultante.getDireccion() + " la magnitud es = " + resultante.getMagnitud());
		System.out.println("El punto destino es: " + destino.x + " , " + destino.y);
		//System.out.println("Mi pos es: " + mipos.x + " , " + mipos.y);
		
		return destino;
	}
	
}
